﻿#include "EditorOutputAbilityView.h"

#include "Widgets/TextWidget.h"
#include "Widgets/EditorScrollWidget.h"
#include "Widgets/Positioners/VerticalPositionerWidget.h"   
#include "EditorOutputAbilityViewModel.h"

#include "Widgets/Positioners/HorizontalPositionerWidget.h"
#include "Widgets/EditorImageButton.h"

#include "Widgets/CanvasWidget.h"

void REditorOutputAbilityView::CreateWidget(TSharedObjectPtr<RWidget> InParent)
{
    auto Root=NewWidget<RWidget>(InParent);
    Root->Anchor.Fill(InParent);
    Root->bClipSubWidgets=true;

    auto ScrollWidget = NewWidget<REditorScrollWidget>(Root);
    ScrollWidget->Anchor.Fill(Root);
    ScrollWidget->OnGetVerticalPercent.Bind([this]()->float
    {
        return OutputViewModel->GetScrollPercent();
    });
    ScrollWidget->OnSetVerticalPercent.Bind([this](float InPercent)
    {
        OutputViewModel->SetScrollPercent(InPercent);
    });

    REditorScrollWidgetWeakPtr WeakScrollWidget=ScrollWidget;

    auto ContentContainer = ScrollWidget->GetContentContainer();
    ContentContainer->Anchor.HorizontalFill(ScrollWidget);
    ContentContainer->Height=[this,WeakScrollWidget]()->float
    {
        return OutputViewModel->GetWholeHeight();
    };

    auto TextWidget=NewWidget<RCanvasWidget>(Root);
    TextWidget->Anchor.Fill(Root);
    TextWidget->Anchor.LeftOffset=5;
    TextWidget->Anchor.RightOffset=5;
    TextWidget->Anchor.TopOffset=5;
    TextWidget->Anchor.BottomOffset=5;
    RCanvasWidgetWeakPtr WeakTextWidget=TextWidget;
    TextWidget->OnPaint.BindLambda([this,WeakTextWidget]()
    {
        WeakTextWidget->Clear();

        if(OutputViewModel->GetLineNum()==0)
        {
            return;
        }

        //1.计算一下可见区域
        float LineHeight=OutputViewModel->GetLineHeight();
        float YPercent=OutputViewModel->GetScrollPercent();

        //内容区域的起始位置，最大不能超过内容区域的倒数第二行
        float YStart=
            CMath::Min(
                YPercent*(OutputViewModel->GetLineNum()-1)*LineHeight
                ,CMath::Max(0.f,(OutputViewModel->GetLineNum()-1)*LineHeight-WeakTextWidget->PresentSize.Y)
            );
        
        //内容区域的结束位置,可能超出内容区域
        float YEnd=YStart+WeakTextWidget->PresentSize.Y;

        int64_t LineStart= YStart/LineHeight;
        float YOffset=LineStart*LineHeight-YStart;

        int64_t LineEnd= YEnd/LineHeight+1;
        if(LineEnd>=OutputViewModel->GetLineNum())
        {
            LineEnd=OutputViewModel->GetLineNum()-1;
        }

        
        //2.paint visible text
        auto Font=OutputViewModel->GetFont();
        int64_t FontSize=OutputViewModel->GetFontSize();
        
        for(int64_t i=LineStart;i<=LineEnd;i++)
        {
            WeakTextWidget->AddText(
                SVec2(0,YOffset+LineHeight*(i-LineStart))
                ,OutputViewModel->GetLine(i)
                ,SColor::White
                ,FontSize
                ,Font
                ,ETextWrapMethod::None //do not wrap for \n at end
            ); 
        }


    });



}

void REditorOutputAbilityView::BindViewModel(TSharedObjectPtr<REditorAbilityViewModel> InViewModel)
{
    Super::BindViewModel(InViewModel);
    OutputViewModel =InViewModel;
}

void REditorOutputAbilityView::FillOperations(TSharedObjectPtr<RWidget> InTitleBar)
{
    auto ButtonBar=NewWidget<RHorizontalPositionerWidget>(InTitleBar);
    ButtonBar->Anchor.VerticalCenterReference=InTitleBar;
    ButtonBar->Anchor.RightReference=InTitleBar;
    ButtonBar->Spacing=OutputViewModel->OperationInterval;
    ButtonBar->Height=OutputViewModel->OperationButtonSize;

    ButtonBar->Width= OutputViewModel->OperationButtonSize*2 + OutputViewModel->OperationInterval;

    auto ClearAllButton=WHE::CreateImageButton(
        OutputViewModel->ClearAllIcon
        ,CString(U"清除输出")
        ,[this](){
            OutputViewModel->ClearLines();
        }
        ,ButtonBar
        ,OutputViewModel->OperationButtonSize
        ,OutputViewModel->OperationButtonImageSize
    );
    ClearAllButton->Anchor.VerticalFill(ButtonBar);
    ClearAllButton->Width=OutputViewModel->OperationButtonSize;

    auto AutoScrollButton=WHE::CreateImageButton(
        std::function<TSharedObjectPtr<RTexture2D>()>(   
        [this]()->TSharedObjectPtr<RTexture2D>
        {
            return OutputViewModel->GetAutoScrollIcon();
        })
        ,CString(U"自动滚动")
        ,[this](){
            OutputViewModel->ToggleAutoScroll();
        }
        ,ButtonBar
        ,OutputViewModel->OperationButtonSize
        ,OutputViewModel->OperationButtonImageSize
    );


}
